package com.freight.msg.serviceimpl;

import com.freight.core.common.constant.CommonConstant;
import com.freight.core.common.utils.SecurityUtil;
import com.freight.core.entity.User;
import com.freight.msg.dao.MessageSendDao;
import com.freight.msg.entity.MessageSend;
import com.freight.msg.mapper.MsgComplainTypesMapper;
import com.freight.msg.service.MessageSendService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 消息发送接口实现
 *
 * @describe
 */
@Slf4j
@Service
@Transactional
public class MessageSendServiceImpl implements MessageSendService {

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private MessageSendDao messageSendDao;

    @Autowired
    private MsgComplainTypesMapper msgComplainTypesMapper;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Override
    public MessageSendDao getRepository() {
        return messageSendDao;
    }

    @Override
    public MessageSend getNewMessageNotice() {
        User u = securityUtil.getCurrUser();

        return msgComplainTypesMapper.getNewMessageNotice(u.getId());
    }

    @Override
    public MessageSend getNewMessageSend() {

        User u = securityUtil.getCurrUser();

        return msgComplainTypesMapper.getNewMessageSend(u.getId());
    }

    @Override
    public void modifyReadState(Long mesId) {
        MessageSend messageSend=messageSendDao.getOne(mesId);
        messageSend.setStatus(1);
        messageSendDao.save(messageSend);
    }

    public static void main(String[] args) {



    }

    @Override
    public long statisticsUnreadMessage() {

        User u = securityUtil.getCurrUser();
        return messageSendDao.count(new Specification<MessageSend>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<MessageSend> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                Path<String> typeField = root.get("userId");
                Path<String> status = root.get("status");

                List<Predicate> list = new ArrayList<Predicate>();

                list.add(cb.equal(typeField, u.getId()));
                list.add(cb.equal(status, 0));

                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                return null;
            }
        });

    }

    @Override
    public MessageSend send(MessageSend messageSend) {
        MessageSend ms = messageSendDao.save(messageSend);
        messagingTemplate.convertAndSendToUser(String.valueOf(messageSend.getUserId()), "/queue/subscribe", "您收到了新的消息");
        return ms;
    }

    @Override
    public void deleteByMessageId(Long messageId) {

        messageSendDao.deleteByMessageId(messageId);
    }

    @Override
    public Page<MessageSend> getAppMessageSendList(Pageable pageable) {
        User u=securityUtil.getCurrUser();
        return messageSendDao.findAll(new Specification<MessageSend>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<MessageSend> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                Path<String> userIdField = root.get("userId");
                List<Predicate> list = new ArrayList<>();
                list.add(cb.equal(userIdField, u.getId()));
                Predicate[] arr = new Predicate[list.size()];
                cq.where(list.toArray(arr));
                cq.orderBy(cb.desc(root.get("createTime")));
                return null;
            }
        }, pageable);
    }

    @Override
    public Page<MessageSend> findByCondition(MessageSend messageSend, Pageable pageable) {

        User user=securityUtil.getCurrUser();

        return messageSendDao.findAll(new Specification<MessageSend>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<MessageSend> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                Path<String> messageIdField = root.get("messageId");
                Path<String> userIdField = root.get("userId");
                Path<Integer> statusField = root.get("status");
                Path<Integer> type = root.get("type");
                List<Predicate> list = new ArrayList<>();

                if(user.getUserType() == 2 && messageSend.getUserId() != null){
                    if (null != messageSend.getMessageId()) {
                        list.add(cb.equal(messageIdField, messageSend.getMessageId()));
                    }
                    if (messageSend.getStatus() != null) {
                        list.add(cb.equal(statusField, messageSend.getStatus()));
                    }
                    Predicate[] array_and=new Predicate[list.size()];
                    Predicate pre_And = cb.and(list.toArray(array_and));

                    List<Predicate> listOr = new ArrayList<Predicate>();
                    listOr.add(cb.equal(userIdField, messageSend.getUserId()));
                    listOr.add(cb.equal(type, "5"));
                    Predicate[] arrayOr = new Predicate[listOr.size()];
                    Predicate pre_Or = cb.or(listOr.toArray(arrayOr));

                    cq.where(pre_And,pre_Or).getRestriction();

                }else {
                    if (null != messageSend.getMessageId()) {
                        list.add(cb.equal(messageIdField, messageSend.getMessageId()));
                    }
                    if (null != messageSend.getUserId()) {
                        list.add(cb.equal(userIdField, messageSend.getUserId()));
                    }
                    if (messageSend.getStatus() != null) {
                        list.add(cb.equal(statusField, messageSend.getStatus()));
                    }
                    Predicate[] arr = new Predicate[list.size()];
                    cq.where(list.toArray(arr));
                }

                cq.orderBy(cb.desc(root.get("createTime")));

                return null;
            }
        }, pageable);
    }

    @Override
    public String getMessageSendNum() {

        User user=securityUtil.getCurrUser();

        if(user.getUserType()==0){
            return msgComplainTypesMapper.getMessageSendNumAdmin(user);

        }else {
            return msgComplainTypesMapper.getMessageSendNum(user);

        }

    }


    @Override
    public void updateStatusByUserId(Long userId, Integer status) {

        messageSendDao.updateStatusByUserId(userId, status);
    }

    @Override
    public void deleteByUserId(Long userId) {

        messageSendDao.deleteByUserId(userId, CommonConstant.MESSAGE_STATUS_READ);
    }

}